import jinja2
import os
import webapp2
from google.appengine.ext import db
import re
import string
import random
import hashlib

class Sites(db.Model):
      url = db.StringProperty(required = True)
      name = db.StringProperty(required = True)
      last_change = db.StringProperty(required = False)
      xpath = db.StringProperty(required = True)
      rate = db.IntegerProperty(required = True)
      pre_pre_content = db.TextProperty(required = False)
      pre_content = db.TextProperty(required = False)

template_dir = os.path.join(os.path.dirname(__file__), '../templates/')
jinja_env = jinja2.Environment(loader = jinja2.FileSystemLoader(template_dir),
                                autoescape = True)

class Render(webapp2.RequestHandler):
      def write(self, *a, **kw):
          self.response.out.write(*a, **kw)

      def render_str(self, template, **params):
          t = jinja_env.get_template(template)
          return t.render(params)

      def render(self, template, **kw):
          self.write(self.render_str(template,**kw))

class DB():
	database = None

	def __init__(self, database):
		self.database = database

	def add(self, database, **kwargs):
		pass
		#for e in kwargs:
			#e
			#kwargs[e]

	def remove(self, Where):
		key = self.database.gql("WHERE :1", Where).get().key().id()
		return self.database.delete(key)

	def read(self, Where = None, Order = None):
		if Where:
			return self.database.gql("WHERE :1", Where).get()
		elif Order:
			return self.database.gql("ORDER BY :1", Order)
		else:
			return self.database.all()

	def write(self, From, Where = None):
		key = self.database.gql("WHERE :2", str(self.database) , Where).get().key().id()
		ob = database.get_by_id(key)
        #  page.content = content
        #  page.title = title
        #  page.put()
        #  self.get_page(key = link, update = True)










class Crypt():

      def make_salt(self):
          return ''.join(random.choice(string.letters) for x in xrange(5))

      def make_pw_hash(self, name, pw,sal):
          if sal=="":
              salt = self.make_salt()
          else:
              salt=sal
          h = hashlib.sha256(name + pw + salt).hexdigest()
          return '%s|%s' % (h, salt)

      def valid_pw(self,name, pw, h):
          has = h.split('|')[0]
          sal = h.split('|')[1]
          nhas = self.make_pw_hash(name, pw,sal).split('|')

          if nhas[0]==has:
              return True


class Users(db.Model):
      username = db.StringProperty(required = True)
      h = db.StringProperty(required = True)

class Sessions():

	PASSWORD_RE = re.compile(r"^.{3,20}$")
	EMAIL_RE = re.compile(r"^[\S]+@[\S]+\.[\S]+$")
	USER_RE = re.compile(r"^[a-zA-Z0-9_-]{3,20}$")

	def __init__(self):
		pass



	def Signup(self, username, password, verify, email = ""):

		PASSWORD_RE = re.compile(r"^.{3,20}$")
		EMAIL_RE = re.compile(r"^[\S]+@[\S]+\.[\S]+$")
		USER_RE = re.compile(r"^[a-zA-Z0-9_-]{3,20}$")

		if (email != ""):

			if (EMAIL_RE.match(email) and USER_RE.match(username) and PASSWORD_RE.match(password) and (password == verify)):

				c = Crypt()
				h = c.make_pw_hash( str(username), str(password), "")
				a = Users(username = str(username), h = h)
				a.put()
				
				return h

			else:
				return False

		else:
			if (USER_RE.match(username) and PASSWORD_RE.match(password) and (password==verify)):

				c = Crypt()
				h = c.make_pw_hash( str(username), str(password), "")
				a = Users(username = str(username), h = h)
				a.put()
				return str(h)

			else:
				return False

	def Login(self, username, password):

		PASSWORD_RE = re.compile(r"^.{3,20}$")
		USER_RE = re.compile(r"^[a-zA-Z0-9_-]{3,20}$")

		if (USER_RE.match(username) and PASSWORD_RE.match(password)):

			c = Crypt()
			u = db.GqlQuery("SELECT * FROM Users WHERE username = :1",username).get()

			if u:
				if c.valid_pw(username, password, u.h):
					return str(u.h)
		return False


	def ValidSession(self, uid):
		h = str(uid)
		u = db.GqlQuery("SELECT * FROM Users WHERE h = :1",h).get()
		if u:
			return u.username
		else:
			return False
